package com.jmult.kit;

import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;

import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;

import com.gif4j.GifDecoder;
import com.gif4j.GifEncoder;
import com.gif4j.GifImage;
import com.gif4j.GifTransformer;

import net.coobird.thumbnailator.Thumbnails;

/**
 * 
 * @author JMult
 *
 */
public class ImageCropKit {

	/**
	 * 获取图片格式
	 * 
	 * @param file 图片文件
	 * @return 图片格式
	 * @throws IOException
	 */
	public static String getImageFormatName(File file) throws IOException {
		String formatName = null;

		ImageInputStream iis = ImageIO.createImageInputStream(file);
		Iterator<ImageReader> imageReader = ImageIO.getImageReaders(iis);
		if (imageReader.hasNext()) {
			ImageReader reader = imageReader.next();
			formatName = reader.getFormatName();
		}

		iis.close();

		return formatName;
	}

	/**
	 * 
	 * @param 原始图片
	 * @param 目标图片物理路径
	 * @param 目标大小
	 * @param 图片类型
	 * @return
	 * @throws IOException
	 */
	public static boolean resizeImage(File file, String saveImg, int maxDim) {
		return zoomImage(file, maxDim, saveImg);
	}

	/**
	 * 
	 * @param 原始图片物理路径
	 * @param 目标图片物理路径
	 * @param 目标大小
	 * @param 图片类型
	 * @return
	 * @throws IOException
	 * @throws JpegFormatException
	 * @throws TagFormatException
	 * @throws ExifFormatException
	 */
	public static boolean resizeImage(String sourceImg, String saveImg, int maxDim) {
		File file = new File(sourceImg);
		return zoomImage(file, maxDim, saveImg);
	}

	private static boolean zoomImage(File file, int maxDim, String saveImg) {
		try {
			BufferedImage bi_image = ImageIO.read(file);

			int imageWidth = bi_image.getWidth();
			int imageHeight = bi_image.getHeight();

			int toWidth = 0;
			int toHeight = 0;

			// 得到合适的压缩大小，按比例。
			if (imageWidth >= imageHeight) {
				toWidth = maxDim;
				toHeight = (int) Math.round((imageHeight * maxDim * 1.0 / imageWidth));
			} else {
				toHeight = maxDim;
				toWidth = (int) Math.round((imageWidth * maxDim * 1.0 / imageHeight));
			}

			Thumbnails.of(file).size(toWidth, toHeight).toFile(new File(saveImg));

		} catch (Exception e) {
			return false;
		}

		return true;
	}

	/**
	 * 载剪图片
	 * 
	 * @param img        原始图片
	 * @param saveImg    图存路径：D:\\img.jpg
	 * @param top        y值
	 * @param left       x值
	 * @param width
	 * @param height
	 * @param formatName 图片类型
	 * @return
	 * @throws IOException
	 */
	public static boolean cropImage(File img, String saveImg, int x, int y, int width, int height, int rotate,
			String formatName) throws IOException {
		File fileDest = new File(saveImg);
		if (!fileDest.getParentFile().exists())
			fileDest.getParentFile().mkdirs();
		formatName = formatName.split("/")[1].toLowerCase();

		// GIF需要特殊处理
		if (formatName.equals(IMAGE_FORMAT.GIF.getValue())) {
			GifImage gif_image = GifDecoder.decode(img);// 创建一个GifImage对象.

			// 有角度旋转
			if (rotate != 0) {
				if (rotate == 90) {
					gif_image = GifTransformer.rotate90Right(gif_image);
				} else if (rotate == -90) {
					gif_image = GifTransformer.rotate90Left(gif_image);
				} else if (rotate == 180 || rotate == -180) {
					gif_image = GifTransformer.rotate180(gif_image);
				} else {
					// double theta = Double.parseDouble(new
					// DecimalFormat("0").format(rotate));
					// theta = Math.PI / (360 / (theta * 2));
					double theta = Math.toRadians(rotate);
					gif_image = GifTransformer.rotate(gif_image, theta, true);
				}
			}

			// 1.缩放重新更改大小.
			// GifImage resizeIMG = GifTransformer.resize(gifImage, width,
			// height, true);
			// 2.剪切图片演示.
			Rectangle rect = new Rectangle(x, y, width, height);
			GifImage gif_crop = GifTransformer.crop(gif_image, rect);
			// 3.按比例缩放
			// GifImage resizeIMG = GifTransformer.scale(gifImage, 1.0,
			// 1.0,true);//参数需要double型
			// 4.其他的方法.还有很多,比如水平翻转，垂直翻转 等等.都是GifTransformer类里面的.
			GifEncoder.encode(gif_crop, fileDest);
			return true;
		} else {
			if (rotate != 0) {
				BufferedImage bi_image = ImageIO.read(img);
				int w = bi_image.getWidth();
				int h = bi_image.getHeight();

				Thumbnails.of(img).size(w, h).rotate(rotate).keepAspectRatio(false).toFile(saveImg);
				Thumbnails.of(saveImg).sourceRegion(x, y, width, height).size(width, height).toFile(saveImg);
				return true;
			} else {
				Thumbnails.of(img).sourceRegion(x, y, width, height).size(width, height).keepAspectRatio(false)
						.toFile(saveImg);
				return true;
			}
		}
	}

	/**
	 * 图片旋转
	 * 
	 * @param bufferedimage
	 * @param degree
	 * @return
	 */
	public static BufferedImage rotate(BufferedImage bufferedimage, int degree) {
		int src_width = bufferedimage.getWidth(null);
		int src_height = bufferedimage.getHeight(null);
		int type = bufferedimage.getColorModel().getTransparency();

		Rectangle rect_des = rotatedSize(new Rectangle(new Dimension(src_width, src_height)), degree);

		BufferedImage bi_image = null;
		bi_image = new BufferedImage(rect_des.width, rect_des.height, type);
		Graphics2D g2;
		(g2 = bi_image.createGraphics()).setRenderingHint(RenderingHints.KEY_INTERPOLATION,
				RenderingHints.VALUE_INTERPOLATION_BILINEAR);

		g2.translate((rect_des.width - src_width) / 2, (rect_des.height - src_height) / 2);
		g2.rotate(Math.toRadians(degree), src_width / 2, src_height / 2);
		g2.drawImage(bufferedimage, null, null);
		g2.dispose();

		return bi_image;
	}

	/**
	 * 设置旋转后的图片宽高
	 * 
	 * @param src
	 * @param rotate
	 * @return
	 */
	public static Rectangle rotatedSize(Rectangle src, int rotate) {
		if (rotate >= 90) {
			if (rotate / 90 % 2 == 1) {
				int temp = src.height;
				src.height = src.width;
				src.width = temp;
			}
			rotate = rotate % 90;
		}

		double r = Math.sqrt(src.height * src.height + src.width * src.width) / 2;
		double len = 2 * Math.sin(Math.toRadians(rotate) / 2) * r;
		double angel_alpha = (Math.PI - Math.toRadians(rotate)) / 2;
		double angel_dalta_width = Math.atan((double) src.height / src.width);
		double angel_dalta_height = Math.atan((double) src.width / src.height);

		int len_dalta_width = (int) (len * Math.cos(Math.PI - angel_alpha - angel_dalta_width));
		int len_dalta_height = (int) (len * Math.cos(Math.PI - angel_alpha - angel_dalta_height));
		int des_width = src.width + len_dalta_width * 2;
		int des_height = src.height + len_dalta_height * 2;
		return new java.awt.Rectangle(new Dimension(des_width, des_height));
	}

	/**
	 * 图片类型
	 */
	public enum IMAGE_FORMAT {
		BMP("bmp"), JPG("jpg"), WBMP("wbmp"), JPEG("jpeg"), PNG("png"), GIF("gif");

		private String value;

		IMAGE_FORMAT(String value) {
			this.value = value;
		}

		public String getValue() {
			return value;
		}

		public void setValue(String value) {
			this.value = value;
		}
	}
}